package com.cenxi.dao.manage;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cenxi.common.convert.RoleConvert;
import com.cenxi.common.dto.RoleDTO;
import com.cenxi.common.result.PageReq;
import com.cenxi.common.result.PageResp;
import com.cenxi.common.result.Req;
import com.cenxi.common.result.Resp;
import com.cenxi.common.vo.RoleVO;
import com.cenxi.dao.entity.Account;
import com.cenxi.dao.entity.Role;
import com.cenxi.dao.entity.RoleMenu;
import com.cenxi.dao.mapper.MenuMapper;
import com.cenxi.dao.mapper.RoleMapper;
import com.cenxi.dao.mapper.RoleMenuMapper;
import com.cenxi.utils.constants.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author cenxi
 * @Date 2023/8/16 11:47
 * @Version 1.0
 */
@Slf4j
@Component
public class ManageRoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Resource
    private RoleConvert roleConvert;

    public Resp<List<RoleVO>> list() {
        List<RoleVO> collect = roleMapper.selectList(new LambdaQueryWrapper<Role>()
                        .eq(Role::getState, Constants.ENABLE))
                .stream().map(item -> roleConvert.toVO(item)).collect(Collectors.toList());
        return Resp.succeed(collect);
    }

    public PageResp<RoleVO> page(PageReq<RoleDTO> req) {
        RoleDTO data = req.getData();
        if (Objects.isNull(data)) {
            return PageResp.error("参数错误");
        }
        LambdaQueryWrapper<Role> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Role::getDeleted, Constants.ENABLE)
                .eq(Objects.nonNull(data.getState()), Role::getState, data.getState())
                .eq(Objects.nonNull(data.getId()), Role::getId, data.getId());
        Page<Role> rolePage = roleMapper.selectPage(new Page<>(req.getPageIndex(), req.getPageSize()), lqw);
        return PageResp.succeed(rolePage.getPages(), rolePage.getTotal(),
                rolePage.hasNext(), rolePage.getRecords().stream()
                        .map(item -> roleConvert.toVO(item)).collect(Collectors.toList()));
    }

    @Transactional(rollbackFor = Exception.class)
    public Resp<Boolean> create(Req<RoleDTO> req) {
        RoleDTO data = req.getData();
        if (Objects.isNull(data)) {
            return Resp.error("角色创建-参数错误");
        }
        Role role = roleConvert.toEntity(data);
        // 检查是否存在相同角色
        if (roleMapper.exists(new LambdaQueryWrapper<Role>()
                .eq(Role::getRoleName, role.getRoleName())
                .eq(Role::getState, Constants.ENABLE))) {
            return Resp.error("角色创建-角色名称已存在");
        }
        if (roleMapper.insert(role) > 0) {
            List<Long> menuIds = data.getMenuIds();
            if (!CollectionUtils.isEmpty(menuIds)) {
                for (Long menuId : menuIds) {
                    RoleMenu roleMenu = new RoleMenu();
                    roleMenu.setRoleId(role.getId());
                    roleMenu.setMenuId(menuId);
                    roleMenuMapper.insert(roleMenu);
                }
            }
            return Resp.succeed(Boolean.TRUE);
        }
        return Resp.error(Boolean.FALSE);
    }

    @Transactional(rollbackFor = Exception.class)
    public Resp<Boolean> edit(Req<RoleDTO> req) {
        RoleDTO data = req.getData();
        if (Objects.isNull(data)) {
            return Resp.error("角色修改-参数错误");
        }
        Role rol = roleMapper.selectById(data.getId());
        if (Objects.nonNull(rol) && !rol.getRoleName().equals(data.getRoleName())
                && roleMapper.exists(new LambdaQueryWrapper<Role>()
                .eq(Role::getRoleName, data.getRoleName())
                .eq(Role::getState, Constants.ENABLE))) {
            return Resp.error("角色修改-角色名称已存在");
        }
        Role role = roleConvert.toEntity(data);
        if (roleMapper.updateById(role) > 0) {
            List<Long> menuIds = data.getMenuIds();
            if (!CollectionUtils.isEmpty(menuIds)) {
                // 修改角色绑定路由/先删后加
                roleMenuMapper.delete(new LambdaQueryWrapper<RoleMenu>()
                        .eq(RoleMenu::getRoleId, data.getId()));
                for (Long menuId : menuIds) {
                    RoleMenu roleMenu = new RoleMenu();
                    roleMenu.setRoleId(role.getId());
                    roleMenu.setMenuId(menuId);
                    roleMenuMapper.insert(roleMenu);
                }
            }
            return Resp.succeed(Boolean.TRUE);
        }
        return Resp.succeed(Boolean.FALSE);
    }

    public Resp<RoleVO> findById(Req<Long> req) {
        if (Objects.isNull(req.getData())) {
            return Resp.error("查询角色数据不合法");
        }
        return Resp.succeed(roleConvert.toVO(roleMapper.selectById(req.getData())));
    }

    public Resp<Boolean> enable(List<Long> data, byte enable) {
        if (CollectionUtils.isEmpty(data)) {
            return Resp.error("角色启用-id错误");
        }
        data.forEach(item -> {
            Role role = new Role();
            role.setId(item);
            role.setState((int) enable);
            roleMapper.updateById(role);
        });
        return Resp.succeed(Boolean.TRUE);
    }

    public Resp<Boolean> disable(List<Long> data, byte disable) {
        if (CollectionUtils.isEmpty(data)) {
            return Resp.error("角色禁用-id错误");
        }
        data.forEach(item -> {
            Role role = new Role();
            role.setId(item);
            role.setState((int) disable);
            roleMapper.updateById(role);
        });
        return Resp.succeed(Boolean.TRUE);
    }

    public Resp<Boolean> deleteById(List<Long> data) {
        if (CollectionUtils.isEmpty(data)) {
            return Resp.error("角色删除-id错误");
        }
        return Resp.succeed(roleMapper.deleteBatchIds(data) > 0);
    }
}
